package com.hyg.common.utils;


import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * Author: huangyuguang
 * Date: 2022/5/5
 * Description: 线程池管理
 */
public class ThreadPoolManager {


    //参数初始化
    private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors();//获取手机CPU线程数
    //核心线程数量大小
    private static final int corepoolsize_off_line = Math.max(2, Math.min(CPU_COUNT - 1, 4));
    //线程池最大容纳线程数
    private static final int maximumPoolSize_off_line = CPU_COUNT * 2 + 1;
    //线程空闲后的存活时长
    private static final int keepAliveTime_off_line = 30;

    //任务过多后，存储任务的一个阻塞队列
    private static BlockingQueue<Runnable> workQueue_off_line = new ArrayBlockingQueue<Runnable>(500);

    //线程池任务满载后采取的任务拒绝策略  减缓新任务提交速度
//  （1）AbortPolicy：直接抛出异常，默认策略；
//  （2）CallerRunsPolicy：用调用者所在的线程来执行任务；
//  （3）DiscardOldestPolicy：丢弃阻塞队列中靠最前的任务，并执行当前任务；
//  （4）DiscardPolicy：直接丢弃任务；
    private static RejectedExecutionHandler rejectHandler = new ThreadPoolExecutor.CallerRunsPolicy();


    //线程池核心线程数
    private static int CORE_POOL_SIZE_RECEIVE = Math.max(2, Math.min(CPU_COUNT - 1, 4));
    //线程池最大线程数
    private static int MAX_POOL_SIZE_RECEIVE = CPU_COUNT * 2 + 1;
    //额外线程空状态生存时间
    private static int KEEP_ALIVE_TIME_RECEIVE = 30;

    private static BlockingQueue workQueue_receive = new LinkedBlockingQueue<Runnable>();//無上限队列
    //线程池
    private static ThreadPoolExecutor receiveExecutor;


    //自带缓存线程池
   /* public static ExecutorService newCachedThreadPool() {
        return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                60L, TimeUnit.SECONDS,
                new SynchronousQueue<Runnable>());
    }*/

    /*发送消息线程池*/
    //线程池核心线程数
    private static int CORE_POOL_SIZE_SEND = 0;
    //线程池最大线程数
    private static int MAX_POOL_SIZE_SEND = 200;
    //额外线程空状态生存时间
    private static int KEEP_ALIVE_TIME_SEND = 30;

    private static BlockingQueue workQueue_SEND = new SynchronousQueue<Runnable>();
    //线程池
    private static ThreadPoolExecutor sendExecutor;


    private ThreadPoolManager() {
    }


    /**
     * 接收的时候是  固定可回收，队列无上限的线程池
     *
     * @return
     */
    public static ThreadPoolExecutor getReceiveInstance() {
        if (null == receiveExecutor) {
            synchronized (ThreadPoolManager.class) {
                if (null == receiveExecutor) {
                    receiveExecutor = new CustomThreadPool(
                            "接收消息线程",
                            CORE_POOL_SIZE_RECEIVE,
                            MAX_POOL_SIZE_RECEIVE,
                            KEEP_ALIVE_TIME_RECEIVE,
                            TimeUnit.SECONDS,
                            workQueue_off_line,
                            threadFactory,
                            rejectHandler);
                }
            }
        }
        //这个方法是允许线程数低于核心线程数时，线程也因为空闲而终止
        receiveExecutor.allowCoreThreadTimeOut(true);//核心线程超时设置
        return receiveExecutor;
    }


    public static ThreadPoolExecutor getCacheInstance() {
        if (null == sendExecutor) {
            synchronized (ThreadPoolManager.class) {
                if (null == sendExecutor) {
                    sendExecutor = new CustomThreadPool(
                            "发送消息线程",
                            CORE_POOL_SIZE_SEND,
                            MAX_POOL_SIZE_SEND,
                            KEEP_ALIVE_TIME_SEND,
                            TimeUnit.SECONDS,
                            workQueue_SEND,
                            threadFactory,
                            rejectHandler);
                }
            }
        }
        return sendExecutor;
    }

    //线程工厂
    private static ThreadFactory threadFactory = new ThreadFactory() {
        private final AtomicInteger integer = new AtomicInteger();

        @Override
        public Thread newThread(Runnable r) {
            return new Thread(r, "myThreadPool thread:" + integer.getAndIncrement());
        }
    };

}
